(function(dicomParser) {
    module("dicomParser.parseDicom");

    function convertToByteArray(jsArray)
    {
        var byteArray = new Uint8Array(jsArray.length);
        var index = 0;
        for(var i=0; i < jsArray.length; i++)
        {
            byteArray[index++] = jsArray[i];
        }

        return byteArray;
    }
    
    function makeBigEndianTestData()
    {
        var rawData = [
            // Preamble
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            // Prefix
            0x44,0x49,0x43,0x4D,
            // File Meta Information Group Length
            // x00020000          UL         4
            0x02,0x00,0x00,0x00, 0x55,0x4C, 0x04,0x00, 0x9F,0x00,0x00,0x00,
            // File Meta Information Version
            // x00020001          OB        (reserved)   2                   01
            0x02,0x00,0x01,0x00, 0x4F,0x42, 0x00,0x00, 0x02,0x00,0x00,0x00, 0x00,0x01,
            // Media Storage SOP Class UID
            // x00020002          UI         26         1.2.840.10008.5.1.4.1.1.2 (CT)
            0x02,0x00,0x02,0x00, 0x55,0x49, 0x1A,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x30,0x30,0x30,0x38,0x2E,0x35,0x2E,0x31,0x2E,0x34,0x2E,0x31,0x2E,0x31,0x2E,0x32,0x00,
            // Media Storage SOP Instance UID
            // x00020003          UI         40         1.2.840.113704.1.111.3512.1336285465.198
            0x02,0x00,0x03,0x00, 0x55,0x49, 0x28,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x31,0x33,0x37,0x30,0x34,0x2E,0x31,0x2E,0x31,0x31,0x31,0x2E,0x33,0x35,0x31,0x32,0x2E,0x31,0x33,0x33,0x36,0x32,0x38,0x35,0x34,0x36,0x35,0x2E,0x31,0x39,0x38,
            // Transfer Syntax UID
            // x00020010          UI         20         1.2.840.10008.1.2.2 (Explicit VR Big Endian)
            0x02,0x00,0x10,0x00, 0x55,0x49, 0x14,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x30,0x30,0x30,0x38,0x2E,0x31,0x2E,0x32,0x2E,0x32,0x00,
            // Implementation Class UID
            // x00020012          UI         28         1.2.276.0.7230010.3.0.3.6.0
            0x02,0x00,0x12,0x00, 0x55,0x49, 0x1C,0x00, 0x31,0x2E,0x32,0x2E,0x32,0x37,0x36,0x2E,0x30,0x2E,0x37,0x32,0x33,0x30,0x30,0x31,0x30,0x2E,0x33,0x2E,0x30,0x2E,0x33,0x2E,0x36,0x2E,0x30,0x00,
            // Slice Location
            // x00201041          DS               4      "-43"
            0x00,0x20,0x10,0x41, 0x44,0x53, 0x00,0x04, 0x2D,0x34,0x33,0x00,
            // Rows
            // x00280010          US         2          512
            0x00,0x28,0x00,0x10, 0x55,0x53, 0x00,0x02, 0x02,0x00
        ];

        return convertToByteArray(rawData);
    }
    
    function makeExplicitLittleEndianTestData()
    {
        var rawData = [
            // Preamble
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            // Prefix
            0x44,0x49,0x43,0x4D,
            // File Meta Information Group Length
            // x00020000          UL         4
            0x02,0x00,0x00,0x00, 0x55,0x4C, 0x04,0x00, 0x9F,0x00,0x00,0x00,
            // File Meta Information Version
            // x00020001          OB        (reserved)  2                     01
            0x02,0x00,0x01,0x00, 0x4F,0x42, 0x00,0x00, 0x02,0x00,0x00,0x00, 0x00,0x01,
            // Media Storage SOP Class UID
            // x00020002          UI         26         1.2.840.10008.5.1.4.1.1.2 (CT)
            0x02,0x00,0x02,0x00, 0x55,0x49, 0x1A,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x30,0x30,0x30,0x38,0x2E,0x35,0x2E,0x31,0x2E,0x34,0x2E,0x31,0x2E,0x31,0x2E,0x32,0x00,
            // Media Storage SOP Instance UID
            // x00020003          UI         40         1.2.840.113704.1.111.3512.1336285465.198
            0x02,0x00,0x03,0x00, 0x55,0x49, 0x28,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x31,0x33,0x37,0x30,0x34,0x2E,0x31,0x2E,0x31,0x31,0x31,0x2E,0x33,0x35,0x31,0x32,0x2E,0x31,0x33,0x33,0x36,0x32,0x38,0x35,0x34,0x36,0x35,0x2E,0x31,0x39,0x38,
            // Transfer Syntax UID
            // x00020010          UI         20         1.2.840.10008.1.2.1 (Explicit VR Little Endian)
            0x02,0x00,0x10,0x00, 0x55,0x49, 0x14,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x30,0x30,0x30,0x38,0x2E,0x31,0x2E,0x32,0x2E,0x31,0x00,
            // Implementation Class UID
            // x00020012          UI         28         1.2.276.0.7230010.3.0.3.6.0
            0x02,0x00,0x12,0x00, 0x55,0x49, 0x1C,0x00, 0x31,0x2E,0x32,0x2E,0x32,0x37,0x36,0x2E,0x30,0x2E,0x37,0x32,0x33,0x30,0x30,0x31,0x30,0x2E,0x33,0x2E,0x30,0x2E,0x33,0x2E,0x36,0x2E,0x30,0x00,
            // Slice Location
            // x00201041          DS               4      "-43"
            0x20,0x00,0x41,0x10, 0x44,0x53, 0x04,0x00, 0x2D,0x34,0x33,0x00,
            // Rows
            // x00280010          US         2          512
            0x28,0x00,0x10,0x00, 0x55,0x53, 0x02,0x00, 0x00,0x02
        ];

        return convertToByteArray(rawData);
    }
    
    function makeImplicitLittleEndianTestData()
    {
        var rawData = [
            // Preamble
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            // Prefix
            0x44,0x49,0x43,0x4D,
            // File Meta Information Group Length
            // x00020000          UL         4
            0x02,0x00,0x00,0x00, 0x55,0x4C, 0x04,0x00, 0x9D,0x00,0x00,0x00,
            // File Meta Information Version
            // x00020001          OB        (reserved)   2                    01
            0x02,0x00,0x01,0x00, 0x4F,0x42, 0x00,0x00, 0x02,0x00,0x00,0x00, 0x00,0x01,
            // Media Storage SOP Class UID
            // x00020002          UI         26         1.2.840.10008.5.1.4.1.1.2 (CT)
            0x02,0x00,0x02,0x00, 0x55,0x49, 0x1A,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x30,0x30,0x30,0x38,0x2E,0x35,0x2E,0x31,0x2E,0x34,0x2E,0x31,0x2E,0x31,0x2E,0x32,0x00,
            // Media Storage SOP Instance UID
            // x00020003          UI         40         1.2.840.113704.1.111.3512.1336285465.198
            0x02,0x00,0x03,0x00, 0x55,0x49, 0x28,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x31,0x33,0x37,0x30,0x34,0x2E,0x31,0x2E,0x31,0x31,0x31,0x2E,0x33,0x35,0x31,0x32,0x2E,0x31,0x33,0x33,0x36,0x32,0x38,0x35,0x34,0x36,0x35,0x2E,0x31,0x39,0x38,
            // Transfer Syntax UID
            // x00020010          UI         20         1.2.840.10008.1.2 (Implicit VR Little Endian)
            0x02,0x00,0x10,0x00, 0x55,0x49, 0x12,0x00, 0x31,0x2E,0x32,0x2E,0x38,0x34,0x30,0x2E,0x31,0x30,0x30,0x30,0x38,0x2E,0x31,0x2E,0x32,0x00,
            // Implementation Class UID
            // x00020012          UI         28         1.2.276.0.7230010.3.0.3.6.0
            0x02,0x00,0x12,0x00, 0x55,0x49, 0x1C,0x00, 0x31,0x2E,0x32,0x2E,0x32,0x37,0x36,0x2E,0x30,0x2E,0x37,0x32,0x33,0x30,0x30,0x31,0x30,0x2E,0x33,0x2E,0x30,0x2E,0x33,0x2E,0x36,0x2E,0x30,0x00,
            // Slice Location
            // x00201041                          4      "-43"
            0x20,0x00,0x41,0x10, 0x04,0x00, 0x00,0x00, 0x2D,0x34,0x33,0x00,
            // Rows
            // x00280010                      2          512
            0x28,0x00,0x10,0x00, 0x02,0x00, 0x00,0x00, 0x00,0x02
        ];

        return convertToByteArray(rawData);
    }
    
    function assertMetaHeaderElements(dataSet, transferSyntax, groupLength) {
        equal(dataSet.uint32('x00020000'), groupLength, "(0002,0000) was not read correctly");
        equal(dataSet.uint16('x00020001'), 256, "(0002,0001) was not read correctly");
        equal(dataSet.string('x00020002'), "1.2.840.10008.5.1.4.1.1.2", "(0002,0002) was not read correctly");
        equal(dataSet.string('x00020003'), "1.2.840.113704.1.111.3512.1336285465.198", "(0002,0003) was not read correctly");
        equal(dataSet.string('x00020010'), transferSyntax, "(0002,0010) was not read correctly");
        equal(dataSet.string('x00020012'), "1.2.276.0.7230010.3.0.3.6.0", "(0002,0012) was not read correctly");
    }

    test("parseDicom bigEndian", function() {
        // Arrange
        var byteArray = makeBigEndianTestData();

        // Act
        var dataSet = dicomParser.parseDicom(byteArray);

        // Assert
        assertMetaHeaderElements(dataSet, "1.2.840.10008.1.2.2", 159);
        equal(dataSet.uint16('x00280010'), 512, "(0028,0010) was not read correctly");
        equal(dataSet.string('x00201041'), "-43", "(0020,1041) was not read correctly");
    });
    
    test("parseDicom explicitLittleEndian", function() {
        // Arrange
        var byteArray = makeExplicitLittleEndianTestData();

        // Act
        var dataSet = dicomParser.parseDicom(byteArray);

        // Assert
        assertMetaHeaderElements(dataSet, "1.2.840.10008.1.2.1", 159);
        equal(dataSet.uint16('x00280010'), 512, "(0028,0010) was not read correctly");
        equal(dataSet.string('x00201041'), "-43", "(0020,1041) was not read correctly");
    });
    
    test("parseDicom implicitLittleEndian", function() {
        // Arrange
        var byteArray = makeImplicitLittleEndianTestData();

        // Act
        var dataSet = dicomParser.parseDicom(byteArray);

        // Assert
        assertMetaHeaderElements(dataSet, "1.2.840.10008.1.2", 157);
        equal(dataSet.uint16('x00280010'), 512, "(0028,0010) was not read correctly");
        equal(dataSet.string('x00201041'), "-43", "(0020,1041) was not read correctly");
    });


})(dicomParser);